package com.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.content.App;
import com.dao.AppointDAO;
import com.dao.EquipDAO;
import com.dao.UserDAO;
import com.model._do.AppointmentDO;
import com.model._do.EquipmentDO;
import com.model._do.SignUpDO;
import com.model._do.UserDO;
import com.model.dto.AppointPastDTO;
import com.model.dto.SuperviseDTO.AppointInfo;
import com.model.dto.SuperviseDTO.Search.AppointSearch;
import com.mysql.cj.util.StringUtils;
import com.service.AppointmentService;
import com.util.DateUtil;
import com.util.LocationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service("appointmentService")
public class AppointmentServiceImpl implements AppointmentService {

    @Autowired
    private AppointDAO appointDAO;

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private EquipDAO equipDAO;

    @Override
    public void doAgreeAppoint(AppointmentDO appoint) {
        AppointmentDO old = appointDAO.getById(appoint);
        if(appoint.getDoAppointEr().equals(old.getDoAppointEr())){
            old.setDoAgreement("1");
        } else {
            old.setEdAgreement("1");
        }
        appointDAO.flushAppoint(old);
    }

    @Override
    public void doRejectAppoint(AppointmentDO appoint) throws Exception {
        Calendar now = Calendar.getInstance();
        Date appointDate = appoint.getAppointmentTime();

        //now时间在appoint时间之后了，表示appoint已经在now之前的时间开始了，则不可取消
        if(appointDate.compareTo(now.getTime()) < 0){
            throw new Exception();
        }
        AppointmentDO old = appointDAO.getById(appoint);
        if(appoint.getDoAppointEr().equals(old.getDoAppointEr())){
            old.setDoAgreement("0");
        } else {
            old.setEdAgreement("0");
        }
        appointDAO.flushAppoint(old);
    }


    public List<AppointmentDO> getAppointIfExist(String doctorId, String equipId){
        HashMap<String, Object> searchMap = new HashMap<>();
        searchMap.put("userId", doctorId);
        searchMap.put("equipId", equipId);
        searchMap.put("tomorrow",DateUtil.getZero(2));
        return appointDAO.getIfExistAppoint(searchMap);
    }

    @Override
    public List<AppointInfo> getAppointInfo(AppointSearch search) {
        List<AppointmentDO> appointList = appointDAO.searchAppoint(search);
        List<AppointInfo> infoList = new ArrayList<>();
        for (AppointmentDO appoint: appointList
             ) {
            AppointInfo info = new AppointInfo();
            info.setAppoint(appoint);
            String equipId = appoint.getDoType().equals("EQUIP")? appoint.getDoAppointEr(): appoint.getAppointEd();
            String doctorId = appoint.getDoType().equals("DOCTOR")? appoint.getDoAppointEr(): appoint.getAppointEd();
            UserDO doctor = userDAO.getUserByUserId(doctorId);
            if(LocationUtil.filterLocation(JSONObject.parseObject(doctor.getUserLocation()), search)){

            } else {
                continue;
            }
            info.setDoctor(doctor);
            info.setEquip(equipDAO.getEquipmentByEquipId(equipId));
            infoList.add(info);
        }
        return infoList;
    }

    @Override
    public HashMap<String, Integer> getPie() {
        HashMap<String, Integer> map = new HashMap<>();
        map.put("doctorReject", appointDAO.getDoctorReject().size());
        map.put("patientReject", appointDAO.getPatientReject().size());
        map.put("doctorNotAgr", appointDAO.getDoctorNotAgr().size());
        map.put("patientNotAgr", appointDAO.getPatientNotAgr().size());
        map.put("agreeNotCon", appointDAO.getAgreeNotCon().size());
        map.put("agreeCon", appointDAO.getAgreeCon().size());
        return map;
    }

    @Override
    public List<AppointmentDO> getAppointByDocAndEqu(SignUpDO sign, UserDO doctor) throws Exception {
        Map<String, String> searchMap = new HashMap<>();
        searchMap.put("userId", doctor.getUserId());
        searchMap.put("equipId", sign.getEquipId());
        return appointDAO.getAppointmentByDocAndEqu(searchMap);
    }

    @Override
    public List<AppointmentDO> getAppointByEntityId(EquipmentDO equipmentDO) {
        HashMap<String ,Object> hashMap = new HashMap<>();
        hashMap.put("entityId", equipmentDO.getEquipId());
        hashMap.put("tomorrow", DateUtil.getZero(2));
        return appointDAO.getAppointTime(hashMap);
    }

    @Override
    public List<AppointmentDO> getAppointByUser(UserDO user){
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("entityId", user.getUserId());
        hashMap.put("tomorrow", DateUtil.getZero(2));
        return appointDAO.getAppointTime(hashMap);
    }

    @Override
    public List<AppointmentDO> getEntityUnAviliTime(AppointmentDO appoint) {
        HashMap<String , Object> hashMap = new HashMap<>();
        hashMap.put("entityId", appoint.getDoAppointEr());
        hashMap.put("entityId2", appoint.getAppointEd());
        hashMap.put("tomorrow", DateUtil.getZero(2));
        return appointDAO.getAppointTime(hashMap);
    }

    @Override
    public List<AppointPastDTO> getAppointPast(String entityId) {
        List<AppointmentDO> pastAppointList = appointDAO.getAppointPast(entityId);
        return pastAppointList.stream().map(appoint -> this.getAppointPast(appoint,entityId)).collect(Collectors.toList());
    }

    private AppointPastDTO getAppointPast(AppointmentDO appointment, String entityId){
        AppointPastDTO appointPast = new AppointPastDTO();
        appointPast.setAppointment(appointment);
        String entity1 = appointment.getAppointEd();
        String entity2 = appointment.getDoAppointEr();
        UserDO doctor = userDAO.getUserByUserId(entity1.equals(entityId) ? entity2: entity1);
        appointPast.setUser(doctor);
        return appointPast;
    }

    @Override
    public void doAppointmentEquDoc(AppointmentDO appointment) {
        appointDAO.doAppointmentEquDoc(appointment);
    }

    @Override
    public void doConfirmAppoint(AppointmentDO appoint) {
        AppointmentDO old = appointDAO.getById(appoint);
        old.setPerform("1");
        appointDAO.flushAppoint(old);
    }

    @Override
    public void doConfirmOverAppoint(AppointmentDO appoint) {
        AppointmentDO old = appointDAO.getById(appoint);
        old.setPerform("0");
        appointDAO.flushAppoint(old);
    }
}
